Skip to content

feat: Redis,Valkey,MSSQL#10

Merged
Asuniia merged 8 commits into
mainfrom
feat/module
May 19, 2026
Merged

feat: Redis,Valkey,MSSQL#10
Asuniia merged 8 commits into
mainfrom
feat/module

Conversation

@Asuniia
Copy link
Copy Markdown
Contributor

@Asuniia Asuniia commented May 19, 2026

Summary by CodeRabbit

  • New Features

    • Interactive database configuration with menu-driven selection
    • Added support for Redis, Valkey, and MSSQL databases
    • New "Configuration Mode" to choose between new and existing database setups
    • Health checks for database services to monitor availability
  • Improvements

    • Enhanced CLI help text and command organization
    • Updated environment variable handling for agent and dashboard setup
    • Optimized Docker Compose templates for better service reliability

Review Change Stack

@Asuniia Asuniia changed the title Feat/module feat: Feat/module May 19, 2026
@Asuniia Asuniia changed the title feat: Feat/module feat: Redis,Valkey,MSSQL May 19, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR refactors the CLI's database configuration flows to use interactive questionary-based prompts, adds support for additional database engines (Redis, Valkey, MSSQL), updates all Docker Compose service templates with healthchecks and standardized networking, and introduces secure password generation and styled prompts as core utilities.

Changes

Interactive Database Configuration & Service Definition Updates

Layer / File(s) Summary
Core utilities and dependencies
core/utils.py, pyproject.toml
Added generate_password() for secure credential generation and questionary_style for prompt styling. Updated dependencies to include questionary>=2.1.0 and tightened pyyaml>=6.0.3.
Docker Compose service definitions and templates
templates/compose.py, .github/assets/templates/agent.yml, .github/assets/templates/dashboard.yml
Updated all service snippets (PostgreSQL, MariaDB, MongoDB, Firebird, Redis, Valkey, MSSQL) with healthchecks, restart: unless-stopped, and cleaned networking. Updated agent and dashboard templates to use environment variable placeholders (${TZ}, ${LOG_LEVEL}, ${EDGE_KEY}, etc.) instead of hardcoded values.
CLI framework and help system
main.py
Refactored Typer app initialization and command registration to use explicit @app.command() decorators with help text, rich help panels, and no_args_is_help=True. Organized db and config commands under "Configuration" panel.
Agent setup command with interactive database configuration
commands/agent.py
Removed --env CLI option; added interactive "Configuration Mode" selector (new/existing) using questionary. Expanded database engine support with auth variants (MongoDB, Redis, Valkey). Changed credential generation to generate_password(16) and database metadata to use container service hostnames instead of localhost. Updated environment variables (LOG_LEVEL, TZ, POLLING, DATA_PATH) and removed project-name templating.
Dashboard setup command with database mode selection
commands/dashboard.py
Replaced Prompt.ask with questionary-based mode selection (external/internal/custom). Added TZ and LOG_LEVEL environment variables. Implemented mode-specific compose template editing and summary table rows.
Database add command with multi-engine support and compose manipulation
commands/db.py
Refactored to support configuration mode selection. Expanded engine support (PostgreSQL, MySQL/MariaDB, MongoDB±auth, Firebird, Redis±auth, Valkey±auth, MSSQL). Implemented regex-based docker-compose.yml manipulation for snippet injection and volume mount insertion. Per-engine credential and metadata generation using generate_password(16).
Metadata and version updates
CITATION.cff
Updated project citation date-released field.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Portabase/cli#9: Overlaps on Firebird service behavior, compose snippet insertion logic, and database metadata generation in commands/db.py.
  • Portabase/cli#7: Modifies the same commands/agent.py function signature and interactive database setup flows that this PR refactors.

Poem

🐰 With questionary's guide and passwords strong,
The cli dances through engines all day long—
Redis, Valkey, Firebird too in sight,
Healthchecks ticking, every service right!
Templates bloom with vars laid clean and clear,
Database dreams now manifest right here! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main feature additions: support for Redis, Valkey, and MSSQL database engines. However, it is narrow in scope and doesn't capture the broader refactoring of database configuration flows and interactive UI improvements that constitute a significant portion of the changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/module

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
commands/agent.py (1)

316-356: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid persisting type: "mysql" when provisioning a MariaDB container.

Line 316 provisions only AGENT_MARIADB_SNIPPET/db-mariadb-*, but Line 346 stores "type": db_engine. If user selects mysql, metadata says MySQL while runtime is MariaDB, which can break downstream engine-specific handling.

Suggested fix (normalize stored type to actual provisioned engine)
-                elif db_engine == "mariadb" or db_engine == "mysql":
+                elif db_engine in {"mariadb", "mysql"}:
                     mysql_port = get_free_port()
                     db_user = "admin"
                     db_pass = generate_password(16)
                     db_name = f"mysql_{secrets.token_hex(4)}"
                     service_name = f"db-mariadb-{secrets.token_hex(2)}"
@@
                     add_db_to_json(
                         path,
                         {
                             "name": db_name,
                             "database": db_name,
-                            "type": db_engine,
+                            "type": "mariadb",
                             "username": db_user,
                             "password": db_pass,
                             "port": 3306,
                             "host": service_name,
                             "generated_id": str(uuid.uuid4()),
                         },
                     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/agent.py` around lines 316 - 356, The metadata written by
add_db_to_json uses the original db_engine variable which can be "mysql" even
though you provision AGENT_MARIADB_SNIPPET (MariaDB); change the stored type to
reflect the actual provisioned engine by computing a concrete value (e.g., set
actual_engine = "mariadb" when db_engine in ("mariadb","mysql")) and use that
actual_engine in the add_db_to_json call (replace "type": db_engine with "type":
actual_engine); locate the block that creates service_name/var_prefix/mysql_port
and updates volumes_list and modify the add_db_to_json call there to pass the
normalized engine string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CITATION.cff`:
- Line 26: The CITATION.cff's date-released ("date-released: \"2026-04-20\"")
does not reflect the new features in this PR; update the date-released value to
the actual release date for this change or bump the version field (e.g., change
version from 26.04.1 to 26.04.2 or 26.05.x) and set date-released to the new
release date so the CITATION.cff accurately matches the new version and release
timestamp.

In `@commands/agent.py`:
- Around line 174-188: The default port selection for the IntPrompt.ask call
uses a nested ternary that falls through to 27017 (MongoDB) for unknown types,
which incorrectly assigns MongoDB's port to redis/valkey; update the default
expression used when constructing port (the IntPrompt.ask call) to explicitly
return 6379 when db_type is "redis" or "valkey" (place this check before the
final else/fallback), so the mapping handles "postgresql", "firebird", "mssql",
"mysql"/"mariadb", "redis"/"valkey" and then the remaining fallback.

In `@commands/db.py`:
- Around line 208-247: The sqlite branch (when db_engine == "sqlite") finishes
composing the sqlite file, calling add_db_to_json and printing success, but then
falls through into the subsequent non-sqlite compose-manipulation code that uses
snippet and service_name and corrupts docker-compose.yml; fix by inserting an
early continue (or otherwise short-circuit) immediately after the sqlite
handling block (after the console.print and add_db_to_json calls) so the loop
restarts and the later snippet/service_name logic is not executed for sqlite, or
alternatively wrap the later compose-manipulation logic in an explicit if
db_engine != "sqlite" guard to prevent the malformed volume insertion.

In `@pyproject.toml`:
- Around line 12-15: Remove the duplicate pyyaml dependency entry in the
dependency list in pyproject.toml by deleting the older "pyyaml >=6.0.0" line
and keeping only "pyyaml>=6.0.3"; ensure the dependencies array contains a
single pyyaml entry ("pyyaml>=6.0.3") to avoid ambiguity.

In `@templates/compose.py`:
- Around line 37-41: The healthcheck CMD-SHELL invocations use unquoted
${PASSWORD} which can be interpreted by the shell if the generated password
contains special characters; update each healthcheck test that calls
["CMD-SHELL", "mariadb-admin ping -h localhost -u ${USER} -p${PASSWORD}"]
(occurrences near healthcheck blocks using CMD-SHELL) to quote the password so
the shell receives it literally (e.g., -p"${PASSWORD}"), ensuring the quotes
wrap only the variable and preserving other arguments.
- Around line 198-200: The current healthcheck under the healthcheck block uses
a brittle /proc/net/tcp6 grep pattern; replace healthcheck.test with a stable
readiness probe that actually verifies MSSQL is accepting connections (for
example use a TCP port check like "CMD-SHELL", "nc -z localhost 1433" or a
proper SQL readiness command using sqlcmd: "CMD-SHELL", "bash -c 'until
/opt/mssql-tools/bin/sqlcmd -S localhost -U \"$MSSQL_USER\" -P
\"$MSSQL_PASSWORD\" -Q \"SELECT 1\" >/dev/null 2>&1; do sleep 1; done'"). Ensure
you update the healthcheck.interval as needed and keep the change scoped to the
healthcheck.test entry so the container reports healthy only when MSSQL
responds.

---

Outside diff comments:
In `@commands/agent.py`:
- Around line 316-356: The metadata written by add_db_to_json uses the original
db_engine variable which can be "mysql" even though you provision
AGENT_MARIADB_SNIPPET (MariaDB); change the stored type to reflect the actual
provisioned engine by computing a concrete value (e.g., set actual_engine =
"mariadb" when db_engine in ("mariadb","mysql")) and use that actual_engine in
the add_db_to_json call (replace "type": db_engine with "type": actual_engine);
locate the block that creates service_name/var_prefix/mysql_port and updates
volumes_list and modify the add_db_to_json call there to pass the normalized
engine string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ef5659c0-d92d-4b92-b224-3621d57edeb2

📥 Commits

Reviewing files that changed from the base of the PR and between 5889f36 and be843f7.

📒 Files selected for processing (10)
  • .github/assets/templates/agent.yml
  • .github/assets/templates/dashboard.yml
  • CITATION.cff
  • commands/agent.py
  • commands/dashboard.py
  • commands/db.py
  • core/utils.py
  • main.py
  • pyproject.toml
  • templates/compose.py
📜 Review details
🧰 Additional context used
🪛 Ruff (0.15.13)
main.py

[warning] 25-25: Boolean-typed positional argument in function definition

(FBT001)

commands/db.py

[warning] 155-155: Unnecessary else after break statement

Remove unnecessary else

(RET508)

core/utils.py

[warning] 70-71: Replace if statement with length = max(length, 8)

Replace with length = max(length, 8)

(PLR1730)

commands/agent.py

[warning] 209-209: Unnecessary else after break statement

Remove unnecessary else

(RET508)


[warning] 316-316: Consider merging multiple comparisons: db_engine in {"mariadb", "mysql"}.

Merge multiple comparisons

(PLR1714)

🔇 Additional comments (8)
commands/db.py (3)

1-34: LGTM!


77-154: LGTM!


401-414: No action needed. The generate_password(16) function explicitly ensures passwords include at least one character from each of four categories: lowercase, uppercase, digits, and special characters. This exceeds MSSQL's complexity requirement of at least three categories, so password generation is compliant.

			> Likely an incorrect or invalid review comment.
main.py (1)

9-12: LGTM!

Also applies to: 25-35, 40-82

commands/dashboard.py (1)

5-22: LGTM!

Also applies to: 52-54, 56-77, 78-128, 137-150, 176-183

core/utils.py (1)

6-9: LGTM!

Also applies to: 15-26, 68-90

.github/assets/templates/agent.yml (1)

2-3: LGTM!

Also applies to: 8-12, 23-23

.github/assets/templates/dashboard.yml (1)

3-43: LGTM!

Also applies to: 45-46

Comment thread CITATION.cff
license: Apache-2.0
version: 26.04.1
date-released: "2026-04-20" No newline at end of file
date-released: "2026-04-20"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

❓ Verification inconclusive

Script executed:

#!/bin/bash
# Description: Check if version 26.04.1 was already tagged/released

# Check for existing git tags matching this version
git tag -l "*26.04.1*"

# Check git log for any commits related to this version
git log --all --grep="26.04.1" --oneline

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0

stdout:

5889f36 chore(release): 26.04.1


Script executed:

# Read the CITATION.cff file to see the full structure
cat CITATION.cff

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0

stdout:

cff-version: 1.0.0
title: Portabase CLI
message: "If you use this software, please cite it as below."
type: software
authors:
  - family-names: Gauthereau
    given-names: Charles
  - family-names: Larcher
    given-names: Killian
repository-code: https://github.com/Portabase/cli
url: https://portabase.io
abstract: "Portabase CLI is a command-line interface tool designed to streamline and enhance the management of Portabase services, providing developers with efficient access to core functionalities directly from the terminal."
keywords:
  - portabase
  - cli
  - command-line
  - tool
  - developer
  - productivity
  - automation
  - database
  - management
  - integration
license: Apache-2.0
version: 26.04.1
date-released: "2026-04-20"


Script executed:

# Check the git history of CITATION.cff to understand recent changes
git log --oneline -20 -- CITATION.cff

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0

stdout:

be843f7 add: mssql,more complex password


Script executed:

# Check when the release commit was made relative to this PR
git log --all --format="%h %ai %s" | grep -E "(release|CITATION)" | head -15

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0

stdout:

5889f36 2026-04-20 12:16:33 +0200 chore(release): 26.04.1
01b59a9 2026-02-17 08:10:16 +0100 chore(release): 26.02.17
b7d0621 2026-02-10 14:05:32 +0100 chore(release): 26.02.6
338fcb5 2026-02-10 14:03:51 +0100 chore(release): 26.02.5
66ea8ca 2026-02-10 13:58:09 +0100 chore(release): 26.02.4
2d077f7 2026-02-10 13:54:27 +0100 chore(release): 26.02.3
feba7a9 2026-02-10 13:51:43 +0100 chore(release): 26.02.2
eb5a448 2026-02-10 13:49:19 +0100 chore(release): 26.02.1
6f9f4b8 2026-01-27 20:49:21 +0100 chore(release): 26.01.27
ed1d8cf 2026-01-27 20:17:43 +0100 chore(release): 26.01.27
f1a6f17 2026-01-27 19:58:28 +0100 chore(release): 26.01.27
246de2c 2026-01-27 19:50:45 +0100 chore(release): 26.01.27b1
dabf648 2026-01-15 16:24:49 +0100 chore(release): 26.01.9
8356aef 2026-01-15 16:24:21 +0100 chore(release): 26.01.8
88ce856 2026-01-15 16:22:22 +0100 chore(release): 26.01.7


Script executed:

# Get the current branch and recent commits
git log --oneline -5

# Get the git diff to see what was changed on line 26 of CITATION.cff
git diff HEAD -- CITATION.cff || git show HEAD:CITATION.cff 2>/dev/null | head -30

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0

stdout:

be843f7 add: mssql,more complex password


Script executed:

# Check if there's a staging area change
git diff --cached -- CITATION.cff || true

Repository: Portabase/cli


Repository: Portabase/cli
Exit code: 0


Update the release date if this version includes new features added after April 20, 2026.

The date-released field is set to "2026-04-20" for version 26.04.1, which matches the historical release timestamp. However, if this PR introduces new features (Redis, Valkey, MSSQL support, interactive configuration) after that date, the release should either use a new version number (e.g., 26.04.2 or 26.05.x) with the appropriate release date, or the date should be updated to reflect when the release will actually occur.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CITATION.cff` at line 26, The CITATION.cff's date-released ("date-released:
\"2026-04-20\"") does not reflect the new features in this PR; update the
date-released value to the actual release date for this change or bump the
version field (e.g., change version from 26.04.1 to 26.04.2 or 26.05.x) and set
date-released to the new release date so the CITATION.cff accurately matches the
new version and release timestamp.

Comment thread commands/agent.py
Comment on lines +174 to +188
port = IntPrompt.ask(
"Port",
default=5432
if db_type == "postgresql"
else (
3050
if db_type == "firebird"
else (
1433
if db_type == "mssql"
else (
3306 if db_type in ["mysql", "mariadb"] else 27017
)
)
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix incorrect default port mapping for Redis/Valkey in existing DB mode.

For db_type == "redis" or db_type == "valkey", the current fallback default becomes 27017, which is MongoDB’s port. This can silently create broken configs if users accept defaults.

Suggested fix
-                    port = IntPrompt.ask(
-                        "Port",
-                        default=5432
-                        if db_type == "postgresql"
-                        else (
-                            3050
-                            if db_type == "firebird"
-                            else (
-                                1433
-                                if db_type == "mssql"
-                                else (
-                                    3306 if db_type in ["mysql", "mariadb"] else 27017
-                                )
-                            )
-                        ),
-                    )
+                    default_ports = {
+                        "postgresql": 5432,
+                        "mysql": 3306,
+                        "mariadb": 3306,
+                        "mongodb": 27017,
+                        "redis": 6379,
+                        "valkey": 6379,
+                        "firebird": 3050,
+                        "mssql": 1433,
+                    }
+                    port = IntPrompt.ask("Port", default=default_ports.get(db_type, 5432))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/agent.py` around lines 174 - 188, The default port selection for the
IntPrompt.ask call uses a nested ternary that falls through to 27017 (MongoDB)
for unknown types, which incorrectly assigns MongoDB's port to redis/valkey;
update the default expression used when constructing port (the IntPrompt.ask
call) to explicitly return 6379 when db_type is "redis" or "valkey" (place this
check before the final else/fallback), so the mapping handles "postgresql",
"firebird", "mssql", "mysql"/"mariadb", "redis"/"valkey" and then the remaining
fallback.

Comment thread commands/db.py
Comment on lines +208 to +247
if db_engine == "sqlite":
db_name = Prompt.ask("Database Name", default="local")
if not db_name.endswith(".sqlite"):
db_name += ".sqlite"

compose_path = path / "docker-compose.yml"
if compose_path.exists():
content = compose_path.read_text()
lines = content.splitlines(keepends=True)
new_lines = []
in_app_service = False
inserted = False

for line in lines:
new_lines.append(line)
if not inserted:
if re.search(r"^ app:", line):
in_app_service = True
elif in_app_service and re.search(r"^ volumes:", line):
new_lines.append(
f" - ./{db_name}:/config/{db_name}\n"
)
in_app_service = False
inserted = True
elif in_app_service and re.search(r"^ [a-zA-Z]", line):
in_app_service = False

with open(compose_path, "w") as f:
f.writelines(new_lines)

add_db_to_json(
path,
{
"name": db_name,
"database": f"/config/{db_name}",
"type": "sqlite",
"generated_id": str(uuid.uuid4()),
},
)
console.print(f"[success]✔ Added SQLite database ({db_name})[/success]")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing early exit corrupts compose file for SQLite.

When db_engine == "sqlite", this block handles compose modification and calls add_db_to_json, but then falls through to lines 416-453 which execute with snippet="" and service_name="". This results in:

  • Line 430 inserting an extra newline
  • Line 434 creating vol_entry = " -data:\n" (malformed volume entry)
  • Lines 436-450 adding this malformed entry to the compose file

Add a continue after line 247 to restart the loop (allowing "back" navigation) or restructure to skip the non-sqlite compose manipulation.

🐛 Proposed fix
                 add_db_to_json(
                     path,
                     {
                         "name": db_name,
                         "database": f"/config/{db_name}",
                         "type": "sqlite",
                         "generated_id": str(uuid.uuid4()),
                     },
                 )
                 console.print(f"[success]✔ Added SQLite database ({db_name})[/success]")
+                break

             elif db_engine == "postgresql":
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@commands/db.py` around lines 208 - 247, The sqlite branch (when db_engine ==
"sqlite") finishes composing the sqlite file, calling add_db_to_json and
printing success, but then falls through into the subsequent non-sqlite
compose-manipulation code that uses snippet and service_name and corrupts
docker-compose.yml; fix by inserting an early continue (or otherwise
short-circuit) immediately after the sqlite handling block (after the
console.print and add_db_to_json calls) so the loop restarts and the later
snippet/service_name logic is not executed for sqlite, or alternatively wrap the
later compose-manipulation logic in an explicit if db_engine != "sqlite" guard
to prevent the malformed volume insertion.

Comment thread commands/db.py
Comment on lines +455 to +488
if db_engine != "sqlite":
write_env_file(path, env_vars)
add_db_to_json(
path,
{
"name": "mirror.fdb" if db_engine == "firebird" else db_name,
"database": db_container_path
if db_engine == "firebird"
else ("0" if db_engine in ["redis", "valkey"] else db_name),
"type": db_engine,
"username": "sa" if db_engine == "mssql" else db_user,
"password": db_pass,
"port": 5432
if db_engine == "postgresql"
else (
3050
if db_engine == "firebird"
else (
3306
if db_engine in ["mysql", "mariadb"]
else (
1433
if db_engine == "mssql"
else (
6379 if db_engine in ["redis", "valkey"] else 27017
)
)
)
),
"host": service_name,
"generated_id": str(uuid.uuid4()),
},
)
break
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Clarify control flow by moving this block inside the else branch.

The if db_engine != "sqlite": block and final break are at the same indentation as the else: on line 155, placing them outside the else block. While this currently works because the "existing" mode breaks at line 154, the structure is confusing—this code is logically part of "new" mode only.

Consider either:

  1. Indenting lines 455-488 to be inside the else: block
  2. Restructuring to use early returns or separate functions for each mode

This also addresses the Ruff hint about "unnecessary else after break" at line 155.

Comment thread pyproject.toml
Comment on lines 12 to 15
"pyyaml >=6.0.0",
"questionary>=2.1.0",
"pyyaml>=6.0.3"
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the duplicate pyyaml requirement.

Line 12 and Line 14 declare pyyaml twice; keep only pyyaml>=6.0.3 to avoid ambiguous dependency maintenance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pyproject.toml` around lines 12 - 15, Remove the duplicate pyyaml dependency
entry in the dependency list in pyproject.toml by deleting the older "pyyaml
>=6.0.0" line and keeping only "pyyaml>=6.0.3"; ensure the dependencies array
contains a single pyyaml entry ("pyyaml>=6.0.3") to avoid ambiguity.

Comment thread templates/compose.py
Comment on lines +37 to +41
healthcheck:
test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u ${USER} -p${PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Quote ${PASSWORD} in CMD-SHELL healthchecks.

Line 38, Line 141, and Line 179 pass ${PASSWORD} unquoted in shell commands. With generated symbols (&, |, etc.), healthchecks can fail or execute unintended shell parsing.

Suggested patch
-      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u ${USER} -p${PASSWORD}"]
+      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u ${USER} -p'${PASSWORD}'"]

-      test: ["CMD-SHELL", "redis-cli -a ${PASSWORD} ping | grep PONG"]
+      test: ["CMD-SHELL", "redis-cli -a '${PASSWORD}' ping | grep PONG"]

-      test: ["CMD-SHELL", "valkey-cli -a ${PASSWORD} ping | grep PONG"]
+      test: ["CMD-SHELL", "valkey-cli -a '${PASSWORD}' ping | grep PONG"]

Also applies to: 140-142, 178-180

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/compose.py` around lines 37 - 41, The healthcheck CMD-SHELL
invocations use unquoted ${PASSWORD} which can be interpreted by the shell if
the generated password contains special characters; update each healthcheck test
that calls ["CMD-SHELL", "mariadb-admin ping -h localhost -u ${USER}
-p${PASSWORD}"] (occurrences near healthcheck blocks using CMD-SHELL) to quote
the password so the shell receives it literally (e.g., -p"${PASSWORD}"),
ensuring the quotes wrap only the variable and preserving other arguments.

Comment thread templates/compose.py
Comment on lines +198 to +200
healthcheck:
test: ["CMD-SHELL", "cat /proc/net/tcp6 | grep -q '059901' || exit 1"]
interval: 10s
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Replace the MSSQL healthcheck probe with a stable readiness check.

Line 199 relies on parsing /proc/net/tcp6 with a hardcoded pattern (059901), which is brittle and can keep the service unhealthy despite successful startup.

Suggested direction
-      test: ["CMD-SHELL", "cat /proc/net/tcp6 | grep -q '059901' || exit 1"]
+      test: ["CMD-SHELL", "nc -z localhost 1433 || exit 1"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
healthcheck:
test: ["CMD-SHELL", "cat /proc/net/tcp6 | grep -q '059901' || exit 1"]
interval: 10s
healthcheck:
test: ["CMD-SHELL", "nc -z localhost 1433 || exit 1"]
interval: 10s
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/compose.py` around lines 198 - 200, The current healthcheck under
the healthcheck block uses a brittle /proc/net/tcp6 grep pattern; replace
healthcheck.test with a stable readiness probe that actually verifies MSSQL is
accepting connections (for example use a TCP port check like "CMD-SHELL", "nc -z
localhost 1433" or a proper SQL readiness command using sqlcmd: "CMD-SHELL",
"bash -c 'until /opt/mssql-tools/bin/sqlcmd -S localhost -U \"$MSSQL_USER\" -P
\"$MSSQL_PASSWORD\" -Q \"SELECT 1\" >/dev/null 2>&1; do sleep 1; done'"). Ensure
you update the healthcheck.interval as needed and keep the change scoped to the
healthcheck.test entry so the container reports healthy only when MSSQL
responds.

@Asuniia Asuniia merged commit 30eb3d6 into main May 19, 2026
1 check passed
@Asuniia Asuniia deleted the feat/module branch May 19, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant